package cc.rengu.redp.common.uid.service;

import cc.rengu.redp.common.uid.dao.TbPubSeqMapper;
import cc.rengu.redp.common.uid.domain.TbPubSeq;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 对TbPubSeq实体提供服务
 *
 * @author lanxiaoshuai
 * @date 2016年12月05日07时28分
 * @see
 */
@Transactional
@Service("TbPubSeqService")
public class TbPubSeqServiceImpl extends ServiceImpl<TbPubSeqMapper, TbPubSeq> implements TbPubSeqService {

    @Override
    public TbPubSeq findSequence(String seqName) {
        return baseMapper.findSequence(seqName);
    }

    @Override
    public void setSeqCurrentBySeqName(TbPubSeq tbPubSeq) {
        baseMapper.update(tbPubSeq, new LambdaQueryWrapper<TbPubSeq>().eq(TbPubSeq::getSeqName, tbPubSeq.getSeqName()));
    }

    /**
     * 生成指定类型序列
     *
     * @param bizUidService
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public String getBizUidGo(BizUidService bizUidService, String seqName) {
        String bizUid;
        Long currSeq;

        try {
            TbPubSeq tbPubSeq = this.findSequence(seqName);

            if (tbPubSeq == null) {
                tbPubSeq = new TbPubSeq();
                currSeq = 1L;
                tbPubSeq.setSeqName(seqName);
                tbPubSeq.setSeqFrom(bizUidService.startFrom());
                tbPubSeq.setSeqCurrent(currSeq);
                tbPubSeq.setSeqPoolSize(bizUidService.poolSize());
                bizUid = bizUidService.combineElement(currSeq);
                this.save(tbPubSeq);
            } else {
                currSeq = tbPubSeq.getSeqCurrent() + 1L;
                if ((currSeq - tbPubSeq.getSeqFrom()) % tbPubSeq.getSeqPoolSize() == 0) {
                    currSeq = tbPubSeq.getSeqFrom();
                }

                tbPubSeq.setSeqCurrent(currSeq);
                this.setSeqCurrentBySeqName(tbPubSeq);

                return bizUidService.combineElement(currSeq);
            }
        } catch (Exception e) {
            log.error("序列号生成失败", e);
            return null;
        }

        return bizUid;
    }
}
